package com.zj.ckproxy.utils;

import com.zj.ckproxy.annotation.CkField;
import org.springframework.core.annotation.AnnotatedElementUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author arthur_zhou
 */
public class FieldUtil {

    /**
     * 获取所有属性 包括父类
     *
     * @param cls 目标类
     * @return 目标类的所有属性
     */
    public static List<Field> getAllFields(final Class<?> cls) {
        if (Objects.isNull(cls)) {
            return Collections.emptyList();
        }
        final List<Field> allFields = new ArrayList<>();
        Class<?> currentClass = cls;
        while (currentClass != null) {
            final Field[] declaredFields = currentClass.getDeclaredFields();
            allFields.addAll(Arrays.asList(declaredFields));
            currentClass = currentClass.getSuperclass();
        }
        return allFields;
    }

    /**
     * 获取属性上的@CkField注解与属性名对应关系
     *
     * @param fields 属性数组
     * @return key-下标位置 value-属性名
     */
    public static Map<Integer, String> getFieldMap(List<Field> fields) {
        if (Objects.isNull(fields) || fields.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<Integer, String> fieldMap = new HashMap<>(8);
        for (Field field : fields) {
            //提升反射性能，关闭安全检查
            field.setAccessible(true);
            CkField annotation = AnnotatedElementUtils.findMergedAnnotation(field, CkField.class);
            if (Objects.nonNull(annotation)) {
                // 获取属性名
                String fieldName = field.getName();
                fieldMap.put(annotation.value(), fieldName);
            }
        }
        return fieldMap;
    }

    /**
     * 获取属性上的@CkField注解与属性名对应关系
     *
     * @param cls 类
     * @return key-下标位置 value-属性名
     */
    public static Map<Integer, String> getFieldMap(Class<?> cls) {
        List<Field> fields = getAllFields(cls);
        return getFieldMap(fields);
    }
}
